package net.csdn.business.common.config.oss;

import com.alibaba.fastjson2.JSON;
import com.aliyun.cdn20180510.Client;
import com.aliyun.cdn20180510.models.RefreshObjectCachesRequest;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyun.oss.model.PutObjectResult;
import com.aliyun.tea.TeaException;
import com.aliyun.teautil.models.RuntimeOptions;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.sts.model.v20150401.AssumeRoleRequest;
import com.aliyuncs.sts.model.v20150401.AssumeRoleResponse;
import lombok.extern.slf4j.Slf4j;
import net.csdn.business.common.config.oss.ApiConfigData;
import net.csdn.business.common.config.oss.AliYunOssProperties;
import net.csdn.business.common.constant.CommonConstants;
import net.csdn.business.common.domain.vo.AliStsTokenVO;
import net.csdn.business.common.enums.ResultCodeEnum;
import net.csdn.business.common.utils.ExceptionUtil;
import net.csdn.business.common.utils.UserInfoParser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.net.URL;
import java.util.Date;

/**
 * @author zhangyl
 * @date 2022/6/13 11:30
 */
@Component
@Slf4j
public class OssWrapperFacade {

    @Autowired
    private AliYunOssProperties properties;

    @Autowired
    private ApiConfigData configData;

    @Autowired
    private IAcsClient client;

    @Autowired
    private Client cdnClient;

    @Autowired
    private AssumeRoleRequest request;


    /**
     * @Author: zhangyl
     * @Description: 前端获取oss上传临时的stsToken
     * @DateTime: 2022/6/18 5:19 下午
     * @Params:
     * @Return
     */
    public AliStsTokenVO getToken() throws Exception {
        String uid = UserInfoParser.getUserId();
        AssumeRoleResponse result = client.getAcsResponse(request);
        log.info("用户上传：{},获取阿里云的oss的stsToken:{}", uid, JSON.toJSON(result));
        if (result == null) {
            ExceptionUtil.throwBizException(ResultCodeEnum.FAIL, "获取临时token失败");
        }
        AliStsTokenVO res = new AliStsTokenVO();
        res.setAccessKeySecret(result.getCredentials().getAccessKeySecret());
        res.setSecurityToken(result.getCredentials().getSecurityToken());
        res.setAccessKeyId(result.getCredentials().getAccessKeyId());
        res.setBucketName(properties.getBucketName());
        res.setEndPoint(properties.getEndpoint());
        res.setExpiration(result.getCredentials().getExpiration());
        res.setUserDir(properties.getUserDir());
        res.setOrgDir(properties.getOrgDir());
        res.setIssueDir(properties.getIssueDir());
        res.setClientDir(properties.getClientDir());
        res.setOssRegionId(properties.getOssRegionId());
        return res;
    }


    public String addOssFile(String path, Boolean isRefresh, byte[] fileByte) throws Exception {
        // Endpoint以杭州为例，其它Region请按实际情况填写。
        AliStsTokenVO stsTokenVO = getToken();
        String endpoint = stsTokenVO.getEndPoint();
        String bucketName = stsTokenVO.getBucketName();
        // 填写步骤五获取的临时访问密钥（AccessKey ID和AccessKey Secret）。
        String accessKeyId = stsTokenVO.getAccessKeyId();
        String accessKeySecret = stsTokenVO.getAccessKeySecret();
        // 填写步骤五获取的安全令牌SecurityToken。
        String securityToken = stsTokenVO.getSecurityToken();
        // 创建OSSClient实例。
        InputStream inputStream = new ByteArrayInputStream(fileByte);
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret, securityToken);
        // 将本地文件exampletest.txt上传至目标存储空间examplebucket下的目录exampledir。
        PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, path, inputStream);
        // 上传文件。
        PutObjectResult result = ossClient.putObject(putObjectRequest);
        log.info("用户上传oss文件结果：{}", JSON.toJSON(result));
        // 关闭OSSClient。
        ossClient.shutdown();

        String url = configData.getImgUrl() + CommonConstants.SLASH + path;
        // 上传结束，刷新相关url的cdn缓存
        if (isRefresh) {
            RefreshObjectCachesRequest refreshObjectCachesRequest = new RefreshObjectCachesRequest()
                    .setObjectPath(url)
                    .setObjectType("File");
            RuntimeOptions runtime = new RuntimeOptions();
            try {
                // 复制代码运行请自行打印 API 的返回值
                cdnClient.refreshObjectCachesWithOptions(refreshObjectCachesRequest, runtime);
            } catch (TeaException error) {
                // 如有需要，请打印 error
                com.aliyun.teautil.Common.assertAsString(error.message);
            } catch (Exception _error) {
                TeaException error = new TeaException(_error.getMessage(), _error);
                // 如有需要，请打印 error
                com.aliyun.teautil.Common.assertAsString(error.message);
            }

        }
        return url;
    }

    public String view(String path) throws Exception {
        String urlStr = null;
        AssumeRoleResponse result = client.getAcsResponse(request);
        String securityToken = result.getCredentials().getSecurityToken();
        String accessKey = result.getCredentials().getAccessKeyId();
        String secretKey = result.getCredentials().getAccessKeySecret();
        // 从STS服务获取临时访问凭证后，您可以通过临时访问密钥和安全令牌生成OSSClient。
        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(properties.getEndpoint(), accessKey, secretKey, securityToken);
        try {
            // 设置签名URL过期时间，单位为毫秒。
            Date expiration = new Date(System.currentTimeMillis() + 3600 * 1000);
            // 生成以GET方法访问的签名URL，访客可以直接通过浏览器访问相关内容。
            URL url = ossClient.generatePresignedUrl(properties.getBucketName(), path, expiration);
            System.out.println(url);
            urlStr = url.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return urlStr;
    }


}